#include "common.hpp"

static const char *optString = "h?";

static const struct option longOpts[] = {
    { "help", no_argument, NULL, 'h' }
};

int main (int argc, char* const argv[]) {
	std::set< key_t > shm_keys;
	shm_keys.insert ( my_ftok(COUNTER|LISTAS) );
//	shm_keys.insert ( my_ftok(COUNTER|SYNC) );

	std::set< key_t > sem_keys;
	// Semaforos de los contadores de botellas.
	sem_keys.insert ( my_ftok(MUTEX|LISTAS) );
//	sem_keys.insert ( my_ftok(MUTEX|SYNC) );
	// Semaforos de las maquinas.
	sem_keys.insert ( my_ftok(MUTEX|TRANSPORTADORA_A) );
	sem_keys.insert ( my_ftok(MUTEX|LLENADORA_0) );
	sem_keys.insert ( my_ftok(MUTEX|AZUCARADORA_0) );
	sem_keys.insert ( my_ftok(MUTEX|TAPADORA) );
	sem_keys.insert ( my_ftok(MUTEX|ETIQUETADORA) );
	sem_keys.insert ( my_ftok(MUTEX|REPOSITOR) );

	std::set< key_t > msq_keys;
	msq_keys.insert ( my_ftok(MSG_QUEUE|TRANSPORTADORA_A) );
	msq_keys.insert ( my_ftok(MSG_QUEUE|LLENADORA_0) );
	msq_keys.insert ( my_ftok(MSG_QUEUE|TAPADORA) );
//	msq_keys.insert ( my_ftok(MSG_QUEUE|ETIQUETADORA) );
	msq_keys.insert ( my_ftok(MSG_QUEUE|REPOSITOR) );
	msq_keys.insert ( my_ftok(MSG_QUEUE|SYNC) );
		
	int longIndex = 0;
	int option = 0;
	while ( (option = getopt_long(argc,argv,optString,longOpts,&longIndex) ) != EOF ) {
		switch (option) {
			case '?':
			case 'h':
			case ':':
				std::cerr << "Proceso para liberación del entorno de ejecución." << std::endl;
				std::cerr << "\tUso: " << argv[0] << " [-h]" << std::endl;
				std::cerr << "\tParametros:" << std::endl;
				std::cerr << "\t\t-h,--help:\tMostrar este mensaje de ayuda." << std::endl;

				return 0;
			default:
				break;
		}
	}

	logger.setColor("\033[2;31m");
	logger << "Destructor: Inicio." << nl;
	for ( std::set<key_t>::const_iterator it = shm_keys.begin(); it != shm_keys.end(); ++it ) {
		ipc::shared_memory<size_t> shm(*it);
		if (shm.get(PERMITS) == 0) {
			if ( shm.destroy() == 0 )
				logger << "Destructor: Memoria compartida destruida. Clave: 0x" << std::hex << *it << "." << nl;
			else 
				error << "Destructor: Imposible destruir memoria compartida. Clave: 0x" << std::hex << *it << "." << nl;
		} else {
			logger << "Destructor: Memoria compartida inexsistente. Clave: 0x" << std::hex << *it << "." << nl;
		}
	}	
	
	for ( std::set<key_t>::const_iterator it = sem_keys.begin(); it != sem_keys.end(); ++it ) {
		ipc::semaphore sem(*it,0); // obtengo un adaptor al primer elemento de cada vector de semaforos.
		if (sem.get(PERMITS) == 0) {
			if (sem.destroy() == 0)
				logger << "Destructor: Semaforo destruido. Clave : 0x" << std::hex << *it << "." << nl;
			else
				error << "Destructor: Imposible destruir semaforo. Clave: 0x" << std::hex << *it << "." << nl;
		} else {
			logger << "Destructor: Semaforo inexsistente. Clave: 0x" << std::hex << *it << "." << nl;
		}
	}

	for ( std::set<key_t>::const_iterator it = msq_keys.begin(); it != msq_keys.end(); ++it ) {
		ipc::messages_queue msq(*it);
		if (msq.get(PERMITS) == 0) {
			if (msq.destroy() == 0)
				logger << "Destructor: Cola de mensajes destruida. Clave: 0x" << std::hex << *it << "." << nl;
			else 
				error << "Destructor: Imposible destruir cola de mensajes. Clave: 0x" << std::hex << *it << "." << nl;
		} else {
			logger << "Destructor: Cola de mensajes inexsistente. Clave: 0x" << std::hex << *it << "." << nl;
		}
	}

	logger << "Destructor: Fin." << nl;
	return 0;
}

